<template>
  <div class="login_container">
    <div class="login_box">
      <div>
        <h2>EasyNode-{{ version }}</h2>
      </div>
      <div v-if="notKey">
        <el-alert title="Error: 用于加密的公钥获取失败，请尝试重新启动或部署服务" type="error" show-icon />
      </div>
      <div v-else>
        <el-form
          ref="loginFormRefs"
          :model="loginForm"
          :rules="rules"
          :hide-required-asterisk="true"
          :show-message="false"
          label-suffix="："
          label-width="90px"
          label-position="top"
        >
          <el-form-item prop="loginName" label="用户名">
            <el-input
              v-model.trim="loginForm.loginName"
              type="text"
              placeholder=""
              autocomplete="off"
              :trigger-on-focus="false"
              clearable
              autofocus
            />
          </el-form-item>
          <el-form-item prop="pwd" label="密码">
            <el-input
              v-model.trim="loginForm.pwd"
              type="password"
              placeholder=""
              autocomplete="off"
              :trigger-on-focus="false"
              clearable
              show-password
              @keyup.enter="handleLogin"
            />
          </el-form-item>
          <el-form-item v-show="false" prop="pwd" label="密码">
            <el-input v-model.trim="loginForm.pwd" />
          </el-form-item>
          <el-form-item prop="mfa2Token" label="MFA2验证码">
            <el-input
              v-model="loginForm.mfa2Token"
              type="text"
              placeholder="MFA2应用上的6位数字(未设置可忽略)"
              autocomplete="off"
              :trigger-on-focus="false"
              clearable
              autofocus
              @keyup.enter="handleLogin"
            />
          </el-form-item>
          <el-form-item prop="jwtExpires" label="登录有效期">
            <el-radio-group v-model="expireTime" class="login-indate">
              <el-radio :value="expireEnum.ONE_SESSION">临时</el-radio>
              <el-radio :value="expireEnum.CURRENT_DAY">当天</el-radio>
              <el-radio :value="expireEnum.THREE_DAY">三天</el-radio>
              <el-radio :value="expireEnum.SEVEN_DAY">七天</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-form>
      </div>
      <div class="footer_btns">
        <el-button
          type="primary"
          class="login_btn"
          :loading="loading"
          @click="handleLogin"
        >
          登录
        </el-button>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, getCurrentInstance } from 'vue'
import { RSAEncrypt } from '@utils/index.js'
import { version } from '../../../package.json'

const { proxy: { $store, $api, $message, $router, $messageBox } } = getCurrentInstance()

const expireEnum = reactive({
  ONE_SESSION: 'one_session',
  CURRENT_DAY: 'current_day',
  THREE_DAY: 'three_day',
  SEVEN_DAY: 'seven_day'
})
const expireTime = ref(expireEnum.CURRENT_DAY)
const loginFormRefs = ref(null)
const notKey = ref(false)
const loading = ref(false)
const isHttps = location.protocol.includes('https')
const notHttpsTips = localStorage.getItem('notHttpsTips') === 'true'
const loginForm = reactive({
  loginName: '',
  pwd: '',
  jwtExpires: 1,
  mfa2Token: ''
})
const rules = reactive({
  loginName: { required: true, message: '需输入用户名', trigger: 'change' },
  pwd: { required: true, message: '需输入密码', trigger: 'change' },
  mfa2Token: { required: false, message: '需输入MFA2验证码', trigger: 'change' }
})

const handleLogin = () => {
  loginFormRefs.value.validate().then(async () => {
    let { jwtExpires, loginName, pwd, mfa2Token } = loginForm
    switch (expireTime.value) {
      case expireEnum.ONE_SESSION:
        jwtExpires = '1h' // 会话登录token1小时有效期，浏览器窗口关闭则立即失效
        break
      case expireEnum.CURRENT_DAY:
        jwtExpires = `${ Math.floor((new Date().setHours(24,0,0,0) - Date.now()) / 1000) }s`
        break
      case expireEnum.THREE_DAY:
        jwtExpires = '3d'
        break
      case expireEnum.SEVEN_DAY:
        jwtExpires = '7d'
        break
    }
    const ciphertext = RSAEncrypt(pwd)
    if (ciphertext === -1) return $message.error({ message: '公钥加载失败', center: true })
    loading.value = true
    try {
      let { data, msg } = await $api.login({ loginName, ciphertext, jwtExpires, mfa2Token })
      const { token, uid } = data
      $store.setJwtToken(token, expireEnum.ONE_SESSION === expireTime.value)
      $store.setUser(loginName, uid)
      $message.success({ message: msg || 'success', center: true })
      if (isHttps) return $router.push('/')
      if (notHttpsTips) return $router.push('/')
      $messageBox.confirm(
        'http协议下存在数据劫持风险，外网使用请配置https协议',
        '安全提示',
        {
          confirmButtonText: '我知道了',
          cancelButtonText: '不再提示',
          type: 'warning',
          showCancelButton: true,
          cancelButtonClass: 'el-button--info',
          confirmButtonClass: 'el-button--warning'
        }
      )
        .catch(() => {
          localStorage.setItem('notHttpsTips', 'true')
        })
        .finally(async () => {
          $router.push('/')
        })
    } finally {
      loading.value = false
    }
  })
}

onMounted(async () => {
  if (localStorage.getItem('jwtExpires')) loginForm.jwtExpires = Number(localStorage.getItem('jwtExpires'))
  const { data } = await $api.getPubPem()
  if (!data) {
    notKey.value = true
    return}
  localStorage.setItem('publicKey', data)
  $store.removeLoginInfo()
})
</script>

<style lang="scss" scoped>
.login_container {
  // min-height: 600px;
  height: 100vh;
  width: 100vw;
  overflow-y: auto;
  display: flex;
  justify-content: center;
  align-items: center;
  background: rgba(171, 181, 196, 0.3); // #f0f2f5;
  padding-top: 1px;

  .login_box {
    margin-top: -80px;
    width: 450px;
    min-height: 250px;
    padding: 20px;
    border-radius: 6px;
    background-color: #ffffff;

    h2 {
      text-align: center;
      margin: 25px;
      color: #409eff;
      font-size: 25px;
      background: linear-gradient(to right, #ffc021, #e4d1a1);
      background-clip: text;
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;
      font-weight: 600;
    }

    .footer_btns {
      display: flex;
      justify-content: center;
      align-items: center;
      .login_btn {
        width: 88px;
      }
    }
  }
}

.login-indate {
  display: flex;
  // flex-wrap: nowrap;

  .input {
    margin-left: -25px;
    // width: auto;
  }
}
</style>
